home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / othergnu / ms.zoo / ms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-18  |  10.9 KB  |  654 lines

  1. /*
  2.  * minimal shell for memory hogs on the atariST
  3.  *    - gcc, MWC, or Alcyon C
  4.  *
  5.  * to configure:
  6.  *    edit config.h
  7.  *
  8.  * to compile: 
  9.  *    see file README
  10.  *
  11.  * Builtins:
  12.  *    rm <list of files>
  13.  *    cp <src> <dst>    both <src> <dest> must be files
  14.  *            WARNING: no checks for <src> <dst> being the same
  15.  *    ls {<regular exp>} with no arg ls *.*
  16.  *    cd {<dir>} with no arg cd $HOME
  17.  *    md <dir>
  18.  *    rd <dir>
  19.  *    pwd print working (current) directory
  20.  *    lo logout
  21.  *    @ file    read commands from file, then revert back to stdin.
  22.  *          NO nested @'s allowed.
  23.  *
  24.  * Aliases, Path, Environment:
  25.  *    see config.h
  26.  *
  27.  *    ++jrb    bammi@dsrgsun.ces.cwru.edu
  28.  */
  29.  
  30. #include <osbind.h>
  31.  
  32. #ifdef NULL
  33. #undef NULL
  34. #endif
  35.  
  36. #define NULL 0L        /* avoid stdio like the plague */
  37. #define BSIZE 256    /* size of all purpose buffer  */
  38.  
  39. #define PROMPT Bconws("# ")
  40. #define PRINTI(i) printi((int)i)
  41. #define CRLF Bconws(_crlf)
  42. #define REG  /* register */
  43.  
  44. typedef struct
  45. {
  46.     char    st_sp1[21];    /* Junk        */
  47.     char    st_mode;       /* File attributes */
  48.     short    st_time;       /* Mod Time      */
  49.     short     st_date;       /* Mod date      */
  50.     long    st_size;       /* File size       */
  51.     char    st_name[14];   /* File name       */
  52. } STAT;
  53.  
  54. #ifdef MWC
  55. long _stksize = 128;    /* don't trim this any further!! */
  56. #else
  57. #ifdef __GNUC__
  58. long _stksize = 192;    /* don't trim this any further!! */
  59.              /* gcc needs extra due to inlines */
  60. #else  /* alcyon */
  61. long _STKSIZ = 128;    /* don't trim this any further!! */
  62. #endif
  63. #endif
  64.  
  65. char *_crlf = "\r\n";
  66. int rhandle = -10;    /* some val < -5 */
  67. char buf[BSIZE];
  68. STAT *stat;
  69.  
  70. #include "config.h"    /* all the user configurable stuff in there */
  71.  
  72. #ifdef __GNUC__
  73. #include <stddef.h>
  74. void Bconws(char *);
  75. void printi(int);
  76. char *nextarg(char **);
  77. char *alltolower(char *);
  78. int cd(char *);
  79. int ls(char *);
  80. void putls(STAT *, int);
  81. int rm(char *);
  82. int cp(char *);
  83. int md(char *);
  84. int rd(char *);
  85. int lo(void);
  86. int at(char *);
  87. int pwd(void);
  88. void read_at(char *);
  89. int find_builtin(char *);
  90. int find_alias(char *);
  91. char *existf(char *, char *, char *);
  92. char *find_ext(char *);
  93. int do_command(char *, char *, char *);
  94. int main(void);
  95. extern char *strcpy(char *, char *);
  96. extern char *strcat(char *, char *);
  97. extern char *index(char *, int);
  98. extern size_t strlen(char *);
  99.  
  100. #else
  101.  
  102. int ls(), rm(), cp(), cd(), md(), rd(), lo(), at(), pwd();
  103. extern char *strcpy();
  104. extern char *strcat();
  105. extern char *index();
  106. extern int strlen();
  107.  
  108. #endif
  109.  
  110. /*
  111.  * Builtin commands
  112.  *
  113.  */
  114. typedef struct {
  115.     char    *command;    /* command string    */
  116.     int     (*routine)();    /* routine to invoke    */
  117. } BUILTIN;
  118.  
  119. BUILTIN builtin[] = {
  120.     { "rm", rm },
  121.     { "cp", cp },
  122.     { "ls", ls },
  123.     { "cd", cd },
  124.     { "md", md },
  125.     { "rd", rd },
  126.     { "lo", lo },
  127.     { "@",  at },
  128.     { "pwd", pwd },
  129.     { (char *)NULL, (int (*)())NULL }
  130. };
  131.  
  132.  
  133. void Bconws(s)
  134. REG char *s;
  135. {
  136.     while(*s) Bconout(2, *s++);
  137. }
  138.  
  139. void printi(val)
  140. REG int val;
  141. {
  142.     static int divisors[] = { 10000, 1000, 100, 10, 1 };
  143.     register int first = 0, div_idx = 0;
  144.     register int j;
  145.     
  146.     /* Special Cases */
  147.     if (val == 0)
  148.     {
  149.     Bconout(2, '0');
  150.     }
  151.     else if (val == -32768)
  152.     {
  153.     Bconws("-32768");
  154.     }
  155.     else
  156.     {    
  157.     /* Get digit for each power of 10 and print them, skip leading 0's */
  158.     if (val < 0)
  159.     {
  160.         Bconout(2, '-');
  161.         val = -val;
  162.     }
  163.     
  164.     while( div_idx < 5 )
  165.     {
  166.         if(((j = val / divisors[div_idx]) != 0) || first != 0)
  167.         {
  168.         Bconout(2, j + '0');
  169.         first = 1;
  170.         }
  171.         val %= divisors[div_idx++];
  172.     }
  173.     }
  174. }
  175.  
  176. #define iswhite(c) ((c == ' ') || (c == '\t'))
  177.  
  178. /*
  179.  * return pointer to next arg, and advance q to char following next arg
  180.  */
  181. char *nextarg(q)
  182. REG char **q;
  183. {
  184.     register char *s = *q;
  185.     register char *p;
  186.     
  187.     if(*s == '\0')
  188.     return (char *)NULL;
  189.     while(iswhite(*s)) s++;
  190.     p = s; s++;
  191.     while((!iswhite(*s)) && (*s != '\0')) s++;
  192.     if(*s != '\0')
  193.     {
  194.     *s = '\0';
  195.     *q = ++s;
  196.     }
  197.     else
  198.     *q = s;
  199.     
  200.     return p;
  201. }
  202.  
  203.  
  204. #define isupper(c) ((c >= 'A') && (c <= 'Z'))
  205. #define tolower(c)  (c - 'A' + 'a')
  206.  
  207. char *alltolower(s)
  208. REG char *s;
  209. {
  210.     register char *p = s;
  211.     
  212.     while(*p != '\0')
  213.     {
  214.     if(isupper(*p)) *p = tolower(*p);
  215.     p++;
  216.     }
  217.     return s;
  218. }
  219.  
  220. int cd(s)
  221. REG char *s;
  222. {
  223.     register char *d, *path;
  224.     register int drive;
  225.     
  226.     if(*s == '\0')
  227.     return cd(HOME);
  228.     
  229.     if((d = index(s,':')) == (char *)NULL)
  230.     {
  231.     /* Drive was not specified, must mean the current drive */
  232.     path = s;
  233.     }
  234.     else
  235.     {
  236.     d--;
  237.     if(isupper(*d))
  238.     {
  239.         *d = tolower(*d);
  240.     }
  241.     drive = *d - 'a';
  242.     if(d[2] != '\\')    /* just gave D: */
  243.     {
  244.         /* we will shove in the '\' */
  245.         d[1] = '\\';
  246.         path = &d[1];
  247.     }
  248.     else
  249.         path = &d[2];
  250.     
  251.     /* Set the Drive */
  252.     if(Dsetdrv(drive) < 0)
  253.     {
  254.         Bconws("?drv: "); Bconout(2, *d); CRLF;
  255.         return 2;
  256.     }
  257.     
  258.     }
  259.     
  260.     /* Set the Path */
  261.     if(Dsetpath(path) != 0)
  262.     {
  263.     Bconws("?dir: "); Bconws(path); CRLF;
  264.     return 3;
  265.     }
  266.     return 0;
  267. }
  268.  
  269. int pwd()
  270. {
  271.     char path[32];
  272.     extern char *alltolower();
  273.     
  274.     Bconout(2, (int)(Dgetdrv() + 'a'));
  275.     Bconout(2, ':');
  276.     Dgetpath(path, 0);
  277.     if(*path == '\0')
  278.     {
  279.     path[0] = '\\';
  280.     path[1] = '\0';
  281.     }
  282.     Bconws(alltolower(path)); CRLF;
  283.     return 0;
  284. }
  285.  
  286. #define HASWILD(S) \
  287.     ((index(S, '*') != (char *)NULL) || (index(S, '?') != (char *)NULL))
  288.  
  289. void putls(statbuf, count)
  290. REG STAT *statbuf;
  291. REG int count;
  292. {
  293.     register int len = strlen(statbuf->st_name);
  294.     extern char *alltolower();
  295.     
  296.     if((statbuf->st_mode) & 0x0010)
  297.     {
  298.     /* subtree */
  299.     Bconws(alltolower(statbuf->st_name));
  300.     Bconout(2, '/');
  301.     len++;
  302.     }
  303.     else
  304.     /* file */
  305.     Bconws(alltolower(statbuf->st_name));
  306.     
  307.     if((count & 3) == 3)
  308.     CRLF;
  309.     else
  310.     {
  311.     len = 14 - len;
  312.     while(len--)
  313.         Bconout(2, ' ');
  314.     }
  315. }
  316.  
  317. int ls(s)
  318. REG char *s;
  319. {
  320.     register int count;
  321.     
  322.     if(*s == '\0')
  323.     return ls("*.*");
  324.     
  325.     if(HASWILD(s))
  326.     (void) strcpy(buf, s);
  327.     else
  328.     {
  329.     if(s[(strlen(s)    - 1)] != '\\')
  330.     {
  331.         (void) strcpy(buf, s);
  332.         (void) strcat(buf, "\\");
  333.     }
  334.     else
  335.         (void) strcpy(buf, s);
  336.     (void) strcat(buf, "*.*");
  337.     }
  338.     if(Fsfirst(buf, 0x0020 | 0x0010) != 0)
  339.     {
  340.     Bconws("?match: "); Bconws(buf); CRLF;
  341.     return 1;
  342.     }
  343.     
  344.     count = 0;
  345.     if(!((strcmp(stat->st_name,".") == 0) || 
  346.      (strcmp(stat->st_name, "..") == 0)))
  347.     putls(stat, count++);
  348.     
  349.     while(Fsnext() == 0)
  350.     {
  351.     if(!((strcmp(stat->st_name,".") == 0) || 
  352.          (strcmp(stat->st_name, "..") == 0)))
  353.         putls(stat, count++);
  354.     }
  355.     
  356.     if(count & 3)
  357.     CRLF;
  358.     
  359.     return 0;
  360. }
  361.  
  362. int rm(s)
  363. char *s;
  364. {
  365.     register char *p;
  366.     register int status = 0;
  367.     extern char *nextarg();
  368.     
  369.     while((p = nextarg(&s)) != (char *)NULL)
  370.     {
  371.     if(Fdelete(p) != 0)
  372.     {
  373.         Bconws("?file: "); Bconws(s); CRLF;
  374.         status = 1;
  375.     }
  376.     }
  377.     return status;
  378. }
  379.  
  380. int cp(s)
  381. char *s;
  382. {
  383.     register char *p;
  384.     register int src, dst;
  385.     register long l, k;
  386.     extern char *nextarg();
  387.     
  388.     if((p = nextarg(&s)) == (char *)NULL)
  389.     {
  390.     Bconws("?cp src dst"); CRLF;
  391.     return 1;
  392.     }
  393.     if((src = Fopen(p, 0)) < (-3))
  394.     {
  395.     Bconws("?src: "); Bconws(p); CRLF;
  396.     return src;
  397.     }
  398.     if((p = nextarg(&s)) == (char *)NULL)
  399.     {
  400.     Bconws("?cp src dst"); CRLF;
  401.     k = 2;
  402.     goto rmfin1;
  403.     }
  404.     if((dst = Fcreate(p, 0)) < (-3))
  405.     {
  406.     if((dst = Fopen(p, 1)) < (-3))
  407.     {
  408.         Bconws("?dst: "); Bconws(p); CRLF;
  409.         k = dst;
  410.         goto rmfin1;
  411.     }
  412.     }
  413.     while( (l = Fread(src, (long)BSIZE, buf)) > 0L)
  414.     {
  415.     if((k = Fwrite(dst, l, buf)) != l)
  416.     {
  417.         Bconws("?Write Fail\r\n");
  418.         goto rmfin;
  419.     }
  420.     }
  421.     k = 0;
  422.   rmfin:    
  423.     Fclose(dst);
  424.   rmfin1:
  425.     Fclose(src);
  426.  
  427.     return k;
  428. }
  429.  
  430. int md(s)
  431. char *s;
  432. {
  433.     extern char *nextarg();
  434.     register char *p;
  435.     
  436.     if((p = nextarg(&s)) == (char *)NULL)
  437.     {
  438.     Bconws("?md\r\n");
  439.     return 1;
  440.     }
  441.     return(Dcreate(p));
  442. }
  443.  
  444. int rd(s)
  445. char *s;
  446. {
  447.     extern char *nextarg();
  448.     register char *p;
  449.     
  450.     if((p = nextarg(&s)) == (char *)NULL)
  451.     {
  452.     Bconws("?rd\r\n");
  453.     return 1;
  454.     }
  455.     return(Ddelete(p));
  456. }
  457.  
  458. int lo()
  459. {
  460.     Pterm(0);
  461. }
  462.  
  463. int at(s)
  464. REG char *s;
  465. {
  466.     if((s == (char *)NULL) || (*s == '\0'))    /* dependency !! */
  467.     {
  468.     if(rhandle > (-3))
  469.     {
  470.         Fclose(rhandle);
  471.         rhandle = -10;
  472.     }
  473.     return 0;
  474.     }
  475.     
  476.     if((rhandle = Fopen(s, 0)) < (-3))
  477.     {
  478.     Bconws("?file: "); Bconws(s); CRLF;
  479.     return 1;
  480.     }
  481.     return 0;
  482. }
  483.  
  484. void read_at(buf)
  485. char *buf;
  486. {
  487.     char c;
  488.     register char *p;
  489.     
  490.     p = &buf[2];
  491.     buf[1] = 0;
  492.     while(Fread(rhandle, 1L, &c) == 1L)
  493.     {
  494.     Bconout(2, c);
  495.     if(c == '\r')
  496.     {
  497.         Bconout(2, '\n');
  498.         *p = '\0';
  499.         buf[1] = strlen(&buf[2]);
  500.         Fread(rhandle, 1L, &c);
  501.         return;
  502.     }
  503.     *p++ = c;
  504.     }
  505.     Fclose(rhandle);
  506.     rhandle = -10;
  507.     CRLF;
  508. }
  509.  
  510.  
  511. int find_builtin(s)
  512. REG char *s;
  513. {
  514.     register int i;
  515.     for(i = 0; builtin[i].command != (char *)NULL; i++)
  516.     if(strcmp(s, builtin[i].command) == 0)
  517.         return i;
  518.     return -1;
  519. }
  520.  
  521. int find_alias(s)
  522. REG char *s;
  523. {
  524.     register int i;
  525.     for(i = 0; alias[i].aname != (char *)NULL; i++)
  526.     if(strcmp(s, alias[i].aname) == 0)
  527.         return i;
  528.     return -1;
  529. }
  530.  
  531. char *existf(name, pth, ex)
  532. REG char *name, *pth, *ex;
  533. {
  534.     register char *b = &buf[(BSIZE/2)];
  535.     
  536.     if(*pth != '\0')
  537.     {
  538.     (void) strcpy(b, pth);
  539.     (void) strcat(b, name);
  540.     }
  541.     else
  542.     (void) strcpy(b, name);
  543.     if(*ex != '\0')
  544.     (void) strcat(b, ex);
  545.     if(Fsfirst(b, 0) == 0)
  546.     return b;
  547.     return (char *)NULL;
  548. }
  549.  
  550.  
  551. char *find_ext(s)
  552. REG char *s;
  553. {
  554.     register char *p;
  555.     register int i, j;
  556.     extern char *existf();
  557.     
  558.     for(i = 0; path[i] != (char *)NULL; i++)
  559.     for(j = 0; ext[j] != (char *)NULL; j++)
  560.         if(( p = existf(s, path[i], ext[j])) != (char *)NULL)
  561.         return p;
  562.     return (char *)NULL;
  563. }
  564.  
  565. int do_command(com, optarg, args)
  566. char *com, *optarg, *args;
  567. {
  568.     
  569.     Bconws(com);
  570.     Bconout(2, ' ');
  571.     if(optarg != (char *)NULL)
  572.     {
  573.     Bconws(optarg);
  574.     Bconout(2, ' ');
  575.     }
  576.     Bconws(args); CRLF;
  577.     if(optarg != (char *)NULL)
  578.     {
  579.     buf[(BSIZE/2)] = strlen(optarg) + strlen(args) + 1;
  580.     (void)strcat(strcat(strcpy(&buf[(BSIZE/2+1)], optarg), " "),
  581.              args);
  582.     return (int)Pexec(0, com, &buf[(BSIZE/2)], env);
  583.     }
  584.     else        
  585.     {
  586.     buf[0] = strlen(args);
  587.     (void) strcpy(&buf[1], args);
  588.     return (int)Pexec(0, com, buf, env);
  589.     }
  590. }
  591.  
  592. int main()
  593. {
  594.     register char *com, *args, *line;
  595.     register int i, status;
  596.     
  597.     /* Set Up Stderr */
  598.     Fforce(2,(int)Fdup(1));
  599.     
  600.     stat = (STAT *)Fgetdta();
  601.     
  602.     cd(HOME);
  603.     while(1)
  604.     {
  605.     PROMPT;
  606.     buf[0] = 127;
  607.     if(rhandle > (-3))
  608.         read_at(buf);
  609.     else
  610.     {
  611.         Cconrs(buf);
  612.         Bconout(2, '\n');
  613.     }
  614.     if(buf[1] == 0)
  615.         continue;
  616.     
  617.     buf[(buf[1]+2)] = '\0';
  618.     line = &buf[2];
  619.     com = line;
  620.     
  621.     /* pick up argv[0] */
  622.     while((*line != '\0') && (!iswhite(*line)))
  623.         line++;
  624.     
  625.     if(*line != '\0')
  626.     {
  627.         *line++ = '\0';
  628.     }
  629.     args = line;
  630.     
  631.     status = 0;
  632.     if((i = find_builtin(com)) >= 0)
  633.         status = (*(builtin[i].routine))(args);
  634.     else if ((i = find_alias(com)) >= 0)
  635.         status = do_command(alias[i].adef, alias[i].optarg,
  636.                 args);
  637.     else if ((line = find_ext(com)) != (char *)NULL)
  638.         status = do_command(line, (char *)NULL, args);
  639.     else
  640.     {
  641.         Bconws(com);Bconws(" not found\r\n");
  642.         continue;
  643.     }
  644.     if(status != 0)
  645.     {
  646.         PRINTI(status); CRLF;
  647.     }
  648.     
  649.     }
  650.     return 0;
  651. }
  652.  
  653. /* -eof- */
  654.